package os.t1;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 短作业优先  SJF
 */
public class SJFClient {


    static private double systemTime=0.0;//系统时间
    static private double averageTurnOverTime;//平均周转时间
    static private double averageWeightedTurnOverTime;//平均带权周转时间
    static private double averageWaitTime;//平均等待时间
    public static void main(String[] args) {

        Process process1 = new Process("job1", 112, 13, 0);
        Process process2 = new Process("job2", 34, 678, 0);
        Process process3 = new Process("job3", 13, 3, 0);
        Process process4 = new Process("job4", 98, 9, 0);
        Process process5 = new Process("job5", 55, 0, 0);
        List<Process> processList=new ArrayList<>();
        List<Process> overProcessList=new ArrayList<>();

        processList.add(process1);
        processList.add(process2);
        processList.add(process3);
        processList.add(process4);
        processList.add(process5);

        //按作业的服务时间排序
        Collections.sort(processList, (o1, o2) -> {
            if(o1.getServiceTime()-o2.getServiceTime()>0){
                return 1;
            }
            return -1;
        });

        //找到最先到达的作业下标
        double firstProcess=Double.MAX_VALUE;
        int firstIndex=0;
        for (int i=0;i<processList.size();++i) {
            Process p=processList.get(i);
            if(firstProcess>p.getArriveTime()){
                firstProcess=p.getArriveTime();
                firstIndex=i;
            }
        }
        //处理作业
        while(!processList.isEmpty()){
            //对于第一条到达的作业，无论时间长短优先执行
            if(systemTime==0.0){
                //取出作业
                Process process=processList.get(firstIndex);
                //执行
                //作业开始执行时间
                process.setJobStartTime(systemTime);
                //作业的结束时间=作业开始时间+作业服务时间
                process.setJobEndTime(process.getJobStartTime()+ process.getServiceTime());
                //作业的周转时间=作业的完成时间-作业的到达时间
                process.setJobTurnOverTime(process.getJobEndTime()- process.getArriveTime());
                //作业的带权周转时间=作业的周转时间/作业的服务时间
                process.setJobWeightedTurnOverTime(process.getJobTurnOverTime()/ process.getServiceTime());
                //作业的等待时间=作业的开始时间-作业的到达时间
                process.setJobWaitTime(process.getJobStartTime()- process.getArriveTime());
                //标志位：设置作业为已完成状态
                process.setStatus(1);
                //加入到已完成队列
                overProcessList.add(process);
                //打印作业信息
                System.out.println(process.toString());
                //从等待队列中移除
                processList.remove(firstIndex);
                //修正系统时间
                systemTime=(systemTime+ process.getServiceTime());
            }else{

                //取出作业
                Process process=processList.get(0);
                //修正系统时间
                systemTime=systemTime>process.getArriveTime()?systemTime:process.getArriveTime();
                //执行
                extracted(processList, overProcessList, process);
            }

        }
    }

    private static void extracted(List<Process> processList, List<Process> overProcessList, Process process) {
        //作业开始执行时间
        process.setJobStartTime(systemTime);
        //作业的结束时间=作业开始时间+作业服务时间
        process.setJobEndTime(process.getJobStartTime()+ process.getServiceTime());
        //作业的周转时间=作业的完成时间-作业的到达时间
        process.setJobTurnOverTime(process.getJobEndTime()- process.getArriveTime());
        //作业的带权周转时间=作业的周转时间/作业的服务时间
        process.setJobWeightedTurnOverTime(process.getJobTurnOverTime()/ process.getServiceTime());
        //作业的等待时间=作业的开始时间-作业的到达时间
        process.setJobWaitTime(process.getJobStartTime()- process.getArriveTime());
        //标志位：设置作业为已完成状态
        process.setStatus(1);
        //加入到已完成队列
        overProcessList.add(process);
        //打印作业信息
        System.out.println(process.toString());
        //从等待队列中移除
        processList.remove(0);
        //修正系统时间
        systemTime=(systemTime+ process.getServiceTime());
    }

}
